﻿using System.Text;

namespace YPF.Common.RabbitMQ
{
    public class RabbitmqMessageProvider
    {
        private readonly ILogger logger = LogManager.GetCurrentClassLogger();
        private static readonly RabbitmqMessageProvider provider = new RabbitmqMessageProvider();

        private ConnectionFactory factory;
        private IConnection connection;
        private IModel channel;
        private IBasicProperties properties;
        private MqItemInfo itemInfo;

        public static RabbitmqMessageProvider Instance => provider;

        private RabbitmqMessageProvider()
        {

        }

        public void Init(MqItemInfo itemInfo)
        {
            this.itemInfo = itemInfo;

            factory = new ConnectionFactory
            {
                HostName = itemInfo.Host,
                VirtualHost = itemInfo.VHost,
                Port = int.Parse(itemInfo.Port),
                UserName = itemInfo.UserName,
                Password = itemInfo.Password
            };

            // 心跳
            factory.RequestedHeartbeat = 20;
            // 断线重连
            factory.AutomaticRecoveryEnabled = true;

            connection = factory.CreateConnection();
            channel = connection.CreateModel();
            channel.QueueDeclare(queue: itemInfo.QueueName, durable: true, exclusive: true, autoDelete: false, arguments: null);
            properties = channel.CreateBasicProperties();
            properties.Persistent = true;
        }

        public void SendMessage(string message)
        {
            if (channel != null)
            {
                var body = Encoding.UTF8.GetBytes(message);
                // 发送数据包
                channel.BasicPublish(
                    exchange: "",
                    routingKey: itemInfo.QueueName,
                    basicProperties: properties,
                    body: body);
                logger.Debug($"send msg to mq : {message}");
            }
        }

        public void Dispose()
        {
            if (channel != null)
            {
                if (channel.IsOpen)
                {
                    channel.Close();
                }
            }

            if (connection != null)
            {
                if (connection.IsOpen)
                {
                    connection.Close();
                }
            }

        }
    }
}